package com.jhc.drone.communication.service.impl;


import com.jhc.drone.communication.datagram.command.Command;
import com.jhc.drone.communication.enums.DroneEnum;
import com.jhc.drone.communication.enums.FlyModeEnum;
import com.jhc.drone.communication.enums.WsReqEnum;
import com.jhc.drone.communication.mission.MissionBuilder;
import com.jhc.drone.communication.network.cache.DroneCache;
import com.jhc.drone.communication.service.CmdService;
import com.jhc.drone.communication.service.MissionService;
import com.jhc.drone.communication.vo.CmdVo;
import com.jhc.drone.communication.vo.CommandVo;
import com.jhc.drone.communication.vo.MissionVo;
import com.jhc.drone.communication.vo.PointVo;
import com.jhc.drone.communication.ws.WsEndpoint;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author lcp
 * @date 2025年02月2025/2/20 13:39
 * @describe
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class MissionServiceImpl implements MissionService {

    private final CmdService cmdService;

    @Override
    public void uploadMission(MissionVo missionVo) throws Exception {
        CommandVo commandVo = new CommandVo();
        commandVo.setMissionVo(missionVo);
        commandVo.setWsReqEnum(WsReqEnum.MISSION_UPLOAD);
        commandVo.setSysId(DroneCache.getSysId(missionVo.getSn()));
        MissionBuilder missionBuilder = new MissionBuilder();
        byte[] homeBytes = missionBuilder.setHome(commandVo);
        WsEndpoint.messageProcessor.send(homeBytes, missionVo.getSn());
        Thread.sleep(100);

        byte[] clearBytes = missionBuilder.clearAllMission(commandVo);
        WsEndpoint.messageProcessor.send(clearBytes, missionVo.getSn());
        Thread.sleep(100);

        byte[] countBytes = missionBuilder.missionCount(commandVo);
        WsEndpoint.messageProcessor.send(countBytes, missionVo.getSn());
        Thread.sleep(100);

        byte[] takeoff = missionBuilder.takeoff(commandVo);
        WsEndpoint.messageProcessor.send(takeoff, missionVo.getSn());
        Thread.sleep(100);

        AtomicInteger seq = new AtomicInteger(0);
        int i = 1;
        for (PointVo point : missionVo.getPoints()) {
            byte[] changeSpeed = missionBuilder.changeSpeed(commandVo, point, seq.getAndIncrement());
            WsEndpoint.messageProcessor.send(changeSpeed, missionVo.getSn());

            byte[] waypoint = missionBuilder.waypoint(commandVo, point, seq.getAndIncrement());
            WsEndpoint.messageProcessor.send(waypoint, missionVo.getSn());
            Thread.sleep(100);

            byte[] pointAction = missionBuilder.pointAction(commandVo, seq.getAndIncrement());
            WsEndpoint.messageProcessor.send(pointAction, missionVo.getSn());
            Thread.sleep(100);

            if (i == missionVo.getPoints().size()) {
                byte[] changeSpeed2 = missionBuilder.changeSpeed(commandVo, point, seq.getAndIncrement());
                WsEndpoint.messageProcessor.send(changeSpeed2, missionVo.getSn());
            }
            i++;
        }
        // 启动任务
        new Thread(() -> {
            try {
                startMission(missionVo.getSn());
            } catch (Exception e) {
                log.error("启动任务失败..", e);
            }
        }).start();
    }

    @Override
    public void startMission(String sn) throws Exception {
        CmdVo cmdVo = new CmdVo();
        cmdVo.setSn(sn);
        if (DroneCache.FLY_MODE_MAP.containsKey(sn) && DroneCache.FLY_MODE_MAP.get(sn) != FlyModeEnum.TASK_MODE) {
            cmdVo.setDrone(DroneEnum.MISSION_MODE);
            cmdService.processCmd(cmdVo);
            Thread.sleep(2000);
        }
        cmdVo.setDrone(DroneEnum.ARM);
        cmdService.processCmd(cmdVo);

    }

    @Override
    public void deleteMission(String sn) throws Exception {
        CommandVo commandVo = new CommandVo();
        commandVo.wsReqEnum = WsReqEnum.CLEAR_MISSION;
        commandVo.setSysId(DroneCache.getSysId(sn));
        WsEndpoint.messageProcessor.send(Command.buildCommand(commandVo), sn);
    }
}
